const participantGrid = document.getElementById('participantGrid');
const countdownEl = document.getElementById('countdown');
const statusText = document.getElementById('statusText');
const qrImage = document.getElementById('qrImage');
const qrUrlEl = document.getElementById('qrUrl');
const voteTitleEl = document.getElementById('voteTitle');
const voteDescEl = document.getElementById('voteDesc');
const timerTitleEl = document.getElementById('timerTitle');
function getVoteIdFromUrl() {
  const url = new URL(window.location.href);
  return url.searchParams.get('voteId');
}

let latestState = null;
let countdownTimer = null;

function formatTime(totalSeconds) {
  const clamped = Math.max(0, Number.isFinite(totalSeconds) ? totalSeconds : 0);
  const hours = Math.floor(clamped / 3600)
    .toString()
    .padStart(2, '0');
  const minutes = Math.floor((clamped % 3600) / 60)
    .toString()
    .padStart(2, '0');
  const seconds = Math.floor(clamped % 60)
    .toString()
    .padStart(2, '0');
  return `${hours} : ${minutes} : ${seconds}`;
}

function renderParticipants(state) {
  if (!state || !Array.isArray(state.participants)) {
    participantGrid.innerHTML = '<p class="notice">暂无候选人。</p>';
    return;
  }
  const maxVotes = state.participants.reduce((acc, participant) => {
    return participant.votes > acc ? participant.votes : acc;
  }, 0);
  const leaders = maxVotes > 0 ? state.participants.filter((p) => p.votes === maxVotes).map((p) => p.id) : state.leaders || [];
  const totalVotes = state.participants.reduce((sum, participant) => sum + participant.votes, 0) || 1;

  participantGrid.innerHTML = state.participants
    .map((participant, idx) => {
      const isLeader = leaders.includes(participant.id);
      const ratio = Math.round((participant.votes / totalVotes) * 100);
      return `
        <article class="participant-card ${isLeader ? 'leader' : ''}" style="animation-delay:${idx * 0.05}s;">
          <div class="participant-name">${participant.name}</div>
          <div class="participant-votes">${participant.votes}票</div>
          <div class="participant-progress"><span style="width:${ratio}%"></span></div>
        </article>
      `;
    })
    .join('');
}

function updateCountdown(state) {
  const now = Date.now();
  let remaining = 0;
  let status = state.status;
  if (state.startAt && now < state.startAt) {
    // 未开始
    remaining = Math.floor((state.startAt - now) / 1000);
    countdownEl.textContent = formatTime(remaining);
    timerTitleEl.textContent = '距离投票开始';
    countdownEl.classList.add('not-started');
    countdownEl.classList.remove('closed');
    statusText.textContent = '投票尚未开始';
    return;
  }
  if (state.endsAt && now > state.endsAt) {
    // 已结束
    countdownEl.textContent = '00 : 00 : 00';
    timerTitleEl.textContent = '投票已结束';
    countdownEl.classList.add('closed');
    countdownEl.classList.remove('not-started');
    statusText.textContent = describeStatus({ ...state, status: 'closed' });
    return;
  }
  // 进行中
  if (state.endsAt) {
    remaining = Math.max(0, Math.floor((state.endsAt - now) / 1000));
    countdownEl.textContent = formatTime(remaining);
    timerTitleEl.textContent = '距离投票结束';
  } else {
    countdownEl.textContent = '-- : -- : --';
    timerTitleEl.textContent = '投票倒计时';
  }
  countdownEl.classList.remove('closed');
  countdownEl.classList.remove('not-started');
}

function describeStatus(state) {
  if (state.status === 'closed') {
    if (!state.participants || state.participants.length === 0) {
      return '投票已结束。';
    }
    const maxVotes = state.participants.reduce((acc, participant) => (participant.votes > acc ? participant.votes : acc), 0);
    if (maxVotes === 0) {
      return '投票已结束，暂无有效票。';
    }
    const leaders = state.participants.filter((participant) => participant.votes === maxVotes);
    if (leaders.length === 1) {
      return `投票已结束，冠军：${leaders[0].name}（${leaders[0].votes}票）`;
    }
    const names = leaders.map((leader) => leader.name).join('、');
    return `投票已结束，平局：${names}（${maxVotes}票）`;
  }
  return '投票进行中，实时刷新中…';
}

function scheduleCountdown(state) {
  if (countdownTimer) {
    clearInterval(countdownTimer);
  }
  updateCountdown(state);
  countdownTimer = setInterval(() => {
    if (!latestState) {
      clearInterval(countdownTimer);
      return;
    }
    updateCountdown(latestState);
    // 自动切换状态提示
    const now = Date.now();
    if (latestState.endsAt && now > latestState.endsAt) {
      clearInterval(countdownTimer);
      countdownEl.textContent = '00 : 00 : 00';
      countdownEl.classList.add('closed');
      statusText.textContent = describeStatus({ ...latestState, status: 'closed' });
    }
  }, 1000);
}

function applyState(state) {
  latestState = state;
  renderParticipants(state);
  scheduleCountdown(state);
  // statusText 由 updateCountdown 控制
  // 如果投票已开始或已结束，移除“正在初始化…”
  if (state.status === 'open' || state.status === 'closed') {
    if (statusText.textContent === '正在初始化…') statusText.textContent = '';
  }
}



async function loadQrCode() {
  try {
    const voteId = getVoteIdFromUrl();
    const voteUrl = voteId ? `${window.location.origin}/vote.html?voteId=${encodeURIComponent(voteId)}` : `${window.location.origin}/vote.html`;
    const res = await fetch('/api/qrcode?url=' + encodeURIComponent(voteUrl));
    const data = await res.json();
    qrImage.src = data.qrcode;
    qrUrlEl.textContent = voteUrl;
  } catch (e) {
    qrImage.alt = '二维码加载失败';
    qrUrlEl.textContent = '二维码加载失败';
  }
}

// socket.io 实时接收票数和投票状态
async function getVoteStatusAndOptions() {
  // 获取投票状态和选项及名称
  const voteId = getVoteIdFromUrl();
  if (voteId) {
    const [meta, options] = await Promise.all([
      fetch(`/api/public/votes/${encodeURIComponent(voteId)}`).then(r => r.json()),
      fetch(`/api/votes/${encodeURIComponent(voteId)}/options`).then(r => r.json())
    ]);
    // 解析时间
    let startAt = meta.start ? new Date(meta.start).getTime() : undefined;
    let endsAt = meta.end ? new Date(meta.end).getTime() : undefined;
    // 设置标题
    if (meta.name) voteTitleEl.textContent = meta.name;
    else voteTitleEl.textContent = '实时投票大屏';
    voteDescEl.textContent = meta.status === 'closed' ? '投票已结束' : '倒计时结束后自动锁定投票，并高亮显示领先者。';
    return { status: meta.status, options, startAt, endsAt };
  } else {
    const res = await fetch('/api/settings');
    const settings = await res.json();
    const resOpt = await fetch('/api/options');
    const options = await resOpt.json();
    let startAt = settings.start ? new Date(settings.start).getTime() : undefined;
    let endsAt = settings.end ? new Date(settings.end).getTime() : undefined;
    voteTitleEl.textContent = '实时投票大屏';
    voteDescEl.textContent = '倒计时结束后自动锁定投票，并高亮显示领先者。';
    return { status: settings.vote_status, options, startAt, endsAt };
  }
}

function setupSocketRealtime() {
  const socket = window.io();
  const voteId = getVoteIdFromUrl();
  if (voteId) {
    socket.on('voteUpdate_' + voteId, (data) => {
      renderVoteState('started', data);
    });
  } else {
    socket.on('voteUpdate', (data) => {
      renderVoteState('started', data);
    });
  }
}

async function renderVoteState(status, data) {
  // status: started | undefined
  const { options, startAt, endsAt } = await getVoteStatusAndOptions();
  let now = Date.now();
  let state = {};
  if (status !== 'started') {
    // 未开始，显示所有选项，票数为0
    state = {
      participants: options.map(opt => ({ id: opt.id, name: opt.name, votes: 0 })),
      status: 'not_started',
      startAt,
      endsAt
    };
    applyState(state);
    return;
  }
  // 已开始，正常显示票数
  state = {
    participants: data.map(opt => ({ id: opt.id, name: opt.name, votes: Number(opt.count) })),
    status: 'open',
    startAt,
    endsAt
  };
  applyState(state);
}

// 首次加载二维码和初始票数/状态
loadQrCode();
getVoteStatusAndOptions().then(({ status, options }) => {
  const voteId = getVoteIdFromUrl();
  if (status !== 'started') {
    renderVoteState(status, []);
  } else {
    // 获取当前票数
    const endpoint = voteId ? `/api/votes/${encodeURIComponent(voteId)}/results` : '/api/results';
    fetch(endpoint).then(res => res.json()).then(data => {
      renderVoteState('started', data);
    });
  }
});
setupSocketRealtime();
